//
// Created by d on 10/29/18.
//

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "ShaderSource.h"
#include <fstream>
#include <cstring>

ShaderSource::ShaderSource(string fileName) :
        contentPtr(nullptr) {
    if (!fileName.empty()) {
        content = readFile(fileName);
        this->contentPtr = content.c_str();
    }
}


string ShaderSource::readFile(string fileName) {
    char buf[1024*1024*1];

    ifstream fi(fileName);
    fi.seekg (0, std::ifstream::end);
    int length = static_cast<int>(fi.tellg());
    fi.seekg (0, std::ifstream::beg);
    string fileContent;
    while (fi) {
        fi.read(buf, sizeof(buf));
        buf[length] = 0;
        fileContent += string(buf);
    }
    return fileContent;
}


ShaderSource::operator const char *const *() {
    contentPtr = content.c_str();
    return &contentPtr;
}


bool ShaderProgram::addShaderFromFile(string fileName, GLuint64 shaderType) {
    printf("loading %s\n", fileName.c_str());
    sources.emplace_back(fileName);
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, (const char* const*)sources.back(), nullptr);
    glCompileShader(shader);
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if(status != GL_TRUE){
        printf("FUCK YOU!");
        char buffer[512];
        glGetShaderInfoLog(shader, 512, nullptr, buffer);
        printf("Compile log:%s\n", buffer);
        return false;
    }
    glAttachShader(shaderProgram, shader);
    return true;
}

ShaderProgram::ShaderProgram() : shaderProgram(shaderProgram=0) {
}

void ShaderProgram::Init() {
    shaderProgram = glCreateProgram();
    sources.reserve(200);
}

ShaderProgram::operator GLuint() {
    return shaderProgram;
}
